﻿// <copyright file="HandPosition.cs" company="Ucaya">
// </copyright>
// <author>Ucaya</author>

namespace KinectExtensions.Nui
{
    #region

    using System;
    using System.ComponentModel;
    using System.Linq.Expressions;
    using System.Windows;

    using Microsoft.Research.Kinect.Nui;

    #endregion

    /// <summary>
    ///   TODO: Update summary.
    /// </summary>
    public class HandPosition : INotifyPropertyChanged
    {
        #region Constants and Fields

        /// <summary>
        ///   The is active.
        /// </summary>
        private bool isActive;

        /// <summary>
        ///   The is master.
        /// </summary>
        private bool isMaster;

        /// <summary>
        ///   The joint.
        /// </summary>
        private Joint joint;

        /// <summary>
        ///   The joint id.
        /// </summary>
        private JointID jointId;

        /// <summary>
        ///   The kinect zone.
        /// </summary>
        private IKinectZone kinectZone;

        /// <summary>
        ///   The point.
        /// </summary>
        private Point point;

        /// <summary>
        ///   The time stamp.
        /// </summary>
        private long timeStamp;

        #endregion

        #region Public Events

        /// <summary>
        ///   The property changed.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        #region Public Properties

        /// <summary>
        ///   Gets or sets a value indicating whether IsActive.
        /// </summary>
        public bool IsActive
        {
            get
            {
                return this.isActive;
            }

            set
            {
                if (this.isActive != value)
                {
                    this.isActive = value;
                    this.RaisePropertyChanged(n => n.IsActive);
                }
            }
        }

        /// <summary>
        ///   Gets or sets a value indicating whether IsMaster.
        /// </summary>
        public bool IsMaster
        {
            get
            {
                return this.isMaster;
            }

            set
            {
                if (this.isMaster != value)
                {
                    this.isMaster = value;
                    this.RaisePropertyChanged(n => n.IsMaster);
                }
            }
        }

        /// <summary>
        ///   Gets or sets Joint.
        /// </summary>
        public Joint Joint
        {
            get
            {
                return this.joint;
            }

            set
            {
                this.joint = value;
                this.RaisePropertyChanged(n => n.Joint);
            }
        }

        /// <summary>
        ///   Gets or sets JointId.
        /// </summary>
        public JointID JointId
        {
            get
            {
                return this.jointId;
            }

            set
            {
                if (this.jointId != value)
                {
                    this.jointId = value;
                    this.RaisePropertyChanged(n => n.JointId);
                }
            }
        }

        /// <summary>
        ///   Gets or sets KinectZone.
        /// </summary>
        public IKinectZone KinectZone
        {
            get
            {
                return this.kinectZone;
            }

            set
            {
                if (this.kinectZone != value)
                {
                    this.kinectZone = value;
                    this.RaisePropertyChanged(n => n.KinectZone);
                }
            }
        }

        /// <summary>
        ///   Gets or sets Point.
        /// </summary>
        public Point Point
        {
            get
            {
                return this.point;
            }

            set
            {
                if (this.point != value)
                {
                    this.point = value;
                    this.IsActive = value.X >= 0 && value.X <= 1 && value.Y >= 0 && value.Y <= 1;
                    this.RaisePropertyChanged(n => n.Point);
                }
            }
        }

        /// <summary>
        ///   Gets or sets TimeStamp.
        /// </summary>
        public long TimeStamp
        {
            get
            {
                return this.timeStamp;
            }

            set
            {
                if (this.timeStamp != value)
                {
                    this.timeStamp = value;
                    this.RaisePropertyChanged(n => n.TimeStamp);
                }
            }
        }

        /// <summary>
        ///   Gets or sets TrackingId.
        /// </summary>
        public int TrackingId { get; set; }

        #endregion

        #region Public Methods

        public Point RoundPoint(Point point, int decimalCount = 3)
        {
            return new Point(Math.Round(point.X, decimalCount), Math.Round(point.Y, decimalCount));
        }

        #endregion

        #region Methods

        /// <summary>
        ///   The raise property changed.
        /// </summary>
        /// <param name = "expression">
        ///   The expression.
        /// </param>
        /// <typeparam name = "TProperty">
        /// </typeparam>
        protected void RaisePropertyChanged<TProperty>(Expression<Func<HandPosition, TProperty>> expression)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(this.GetPropertyName(expression)));
            }
        }

        #endregion
    }
}